home *** CD-ROM | disk | FTP | other *** search
/ Cracking 2 / Cracking II..iso / Tools / icedump 6.018 and nticedump 1.9 / wnt / src / nticedump.asm < prev   
Encoding:
Assembly Source File  |  2000-07-26  |  29.3 KB  |  1,191 lines

  1. %include "ntice.inc"
  2. %include "ntddk.inc"
  3.  
  4.     BITS    32
  5.  
  6. PatchData istruc NTIcedumpHdr
  7.     at NTIcedumpHdr.ID,        db NTICEDUMP_ID        ; speaks for itself
  8.     at NTIcedumpHdr.Len,        dw PATCH_HEADER_SIZE    ; header size
  9.     at NTIcedumpHdr.PatchVer,    dw 0100h        ; nticedump patcher version
  10.     at NTIcedumpHdr.Ver,        dd NTICEDUMP_BUILD    ; nticedump version
  11.     at NTIcedumpHdr.SiVer,        dd NTICE_VERSION    ; target SoftICE version
  12.     at NTIcedumpHdr.VA,        dd Init              ; RVA of Call to Init
  13. iend
  14. ; insert any extra data here
  15. ; i.e. Credits string
  16. ; but keep below 64k =)
  17.     db 'IceDump ',VERSION_TO_ASCII(NTICEDUMP_BUILD),' for NTICE ',VERSION_TO_ASCII(NTICE_VERSION),0
  18. .End:
  19.  
  20. PATCH_HEADER_SIZE EQU (PatchData.End - PatchData)
  21. %assign PATCH_ORIGIN_ADJUSTED (PAGEIN_PATCH_ORIGIN - PATCH_HEADER_SIZE)
  22.  
  23.  
  24.     ORG PATCH_ORIGIN_ADJUSTED
  25.  
  26. ;-------------------------------------------------------------------------------
  27. ; Init will be called by NT. Takes 2 DWORDS as params. This call is
  28. ; responsible with the debug extension vector init, as well as "normal"
  29. ; NTICE initialization. It will replace original DriverEntry. The PE entry
  30. ; point will be set to point to this routine.
  31. ;-------------------------------------------------------------------------------
  32. Init:
  33. %if      NTICE_VERSION = 0x322 || NTICE_VERSION = 0x323
  34.  
  35.     call    .delta322
  36. .delta322:
  37.     pop    eax
  38.     sub    eax, .delta322
  39.     lea    ecx, [eax+Init]
  40.     push    ecx
  41.     pop    dword [eax+SELF_REF]
  42. %endif                    ; END 322 & 323 specific initialization patches
  43.  
  44.     push    dword [esp+8]        ; push pRegistryPath
  45.     push    dword [esp+8]        ; push pDriverObject
  46.     call    pNticeInit        ; call NticeDeviceInit
  47.     test    eax, eax        ; EAX = STATUS_SUCCESS ?
  48.     jl    near .return        ; nope, branch error
  49.  
  50.     pushad                ; save'em all
  51.  
  52.     call    .delta
  53. .delta:
  54.     pop    ebp            ; EBP: Current Address
  55.     sub    ebp, .delta        ; 
  56.  
  57. .fixups:
  58.     mov    ecx, MaxSrv        ; initialize loop count
  59.     lea    edi, [ebp+tInternalApiTable]    ; EDI: pointer to internal API table
  60.  
  61. .next_service:
  62.     add    dword [edi], ebp    ; perform fixup
  63.     add    edi, byte 4        ; advance to next slot
  64.     loop    .next_service        ; more API's ?
  65.  
  66. .get_ntoskrnl_ptrs:
  67.     lea    edi, [ebp+CallTable]    ; EBX: pointer to Call Table
  68.     lea    esi, [ebp+tImportNameTable]    ; ESI: pointer to API Names
  69.     mov    ecx, MaxImportId    ; intialize loop count
  70.  
  71. .next_api:
  72.     call    pExpression2Integer    ; return EAX: API virtual address
  73.     jb    .exit            ; Fail extension commands initialization on error
  74.  
  75.     stosd                ; store API pointer in Call table
  76.     inc    esi            ; step to next string
  77.     loop    .next_api
  78.  
  79. .apply_patches:
  80.     mov    ebx, cr0        ; EBX: CR0
  81.     push    ebx            ; save it for later use
  82.     btr    ebx, 16            ; Clear Write Protect bit
  83.     mov    cr0, ebx
  84.  
  85.     mov    byte  [ebp+CRS_END], 0xC3    ; patch retn
  86.     mov    byte  [ebp+PAGEIN_CMDLINE], 0xBE    ; patch mov esi, imm32
  87.     mov    dword [ebp+PAGEIN_PARSER+1], Parser - PAGEIN_PARSER - 5
  88.     mov    dword [ebp+PCI_VENDORS], -1
  89.     lea    eax,  [ebp+Init]
  90.     mov    dword [ebp+dIGNOREFAULTS1], eax    ; let ntoskrnl
  91.     lea    eax,  [ebp+End]            ; handle faults
  92.     mov    dword [ebp+dIGNOREFAULTS2], eax    ; in this range
  93.  
  94. ; hook pINT3_CleanupForPAGEIN
  95.     lea    eax,[ebp+pINT3_CleanupForPAGEIN+0x18]    ; call pMemcopy
  96.     lea    ebx,[ebp+HookCleanupForPAGEIN-4]
  97.     sub    ebx,eax
  98.     mov    [eax],ebx
  99.  
  100.     pop    ebx
  101.     mov    cr0, ebx            ;revert CR0 to normal state
  102.  
  103. .hook_idt:
  104.     mov    dl, 0x60            ; Interrupt Gate DPL = 3
  105.     lea    edi, [ebp+Icall_handler]    ; handler EIP = Icall_handler
  106.     mov    eax, 0xFF            ; target vector 0xFF
  107.     call    pHookInt_IDT            ; Hook IDT
  108.  
  109. .exit:
  110.     popad                    ; restore all registers
  111.  
  112. .return:
  113.     retn    8 ; return to OS (__stdcall always assumed for DriverEntry )
  114.  
  115.  
  116. ;-------------------------------------------------------------------------------
  117. ;
  118. ;-------------------------------------------------------------------------------
  119.  
  120. Parser:
  121.     pushad
  122.     call    .delta
  123. .delta:
  124.     pop    ebp                                     ;
  125.     sub    ebp, .delta
  126.  
  127.     call    pSaveRegs        ; save client State
  128.     call    pSkipWord        ; skip over PAGEIN
  129.     jb    Parse_Help
  130.  
  131.     lodsb
  132.     and    al, 0x5F        ; toupper
  133.     cmp    al, 'D'
  134.     jz    near Parse_Dump
  135.  
  136.     cmp    al, 'S'
  137.     jz    Parse_Suspend
  138.  
  139.     cmp    al, 'R'
  140.     jz    Parse_Resume
  141.  
  142.     cmp    al, 'B'
  143.     jz    Parse_Bhrama
  144.  
  145.     cmp    al, 'L'
  146.     jz    near Parse_Load
  147.  
  148.     jmp    short Parse_Help
  149.  
  150. .error:
  151.     push    ebx
  152.     call    pPrintErrorToCommandWindow
  153.  
  154. .exit:
  155.     call    pRestoreRegs        ; restore client state
  156.     popad
  157.     retn
  158.  
  159. Parse_Help:
  160.     lea    ebx, [ebp+help_d]
  161.     push    ebx
  162.     call    pPrintErrorToCommandWindow
  163.  
  164.     lea    ebx, [ebp+help_s]
  165.     push    ebx
  166.     call    pPrintErrorToCommandWindow
  167.  
  168.     lea    ebx, [ebp+help_r]
  169.     push    ebx
  170.     call    pPrintErrorToCommandWindow
  171.  
  172.     lea    ebx, [ebp+help_b]
  173.     push    ebx
  174.     call    pPrintErrorToCommandWindow
  175.  
  176.     lea    ebx, [ebp+help_l]
  177.     push    ebx
  178.     call    pPrintErrorToCommandWindow
  179.  
  180.     lea    ebx, [ebp+help_v]
  181.     push    ebx
  182.     call    pPrintErrorToCommandWindow
  183.  
  184.     jmp    short Parser.exit
  185.  
  186. Parse_Suspend:
  187. ;    mov    dword [ebp+dClient_EAX], Srv_Suspend
  188.     lea    ebx, [ebp+nim_err]
  189.     jmp    Parser.error
  190.  
  191. Parse_Resume:
  192. ;    mov    dword [ebp+dClient_EAX], Srv_Resume
  193.     lea    ebx , [ebp+nim_err]
  194.     jmp    Parser.error
  195.  
  196. Parse_Bhrama:
  197.     lea    ebx,[ebp+Error_V86]
  198.     test    byte [ebp+dClient_EFLAGS+2],2    ; is client in V86 mode?
  199.     jnz    near Parser.error
  200.  
  201.     lea    ebx,[ebp+Error_PM16]
  202.     lar    eax,[ebp+dClient_CS]        ; is client 32 bit?
  203.     bt    eax,22
  204.     jnc    near Parser.error
  205.  
  206.     lea    ebx,[ebp+Error_PMR0]
  207.     test    byte [ebp+dClient_CS],3        ; is client in ring-0?
  208.     jz    near Parser.error
  209.  
  210.     lea    ebx,[ebp+Error_NoWnd]
  211.     call    pSkipWhiteSpace
  212.     jz    near Parser.error
  213.  
  214.     call    GetAPIs
  215.     lea    ebx,[ebp+Error_API]
  216.     jc    near Parser.error
  217.  
  218.     mov    ebx,cr0
  219.     push    ebx
  220.     btr    ebx,16
  221.     mov    cr0,ebx
  222.  
  223.     mov    eax,[ebp+dClient_EIP]        ; use current EIP
  224.     mov    [ebp+Bhrama_Struc+BhramaComStruc.EIP],eax
  225.  
  226.     mov    edi,esi
  227.     mov    ecx,-1
  228.     xor    eax,eax
  229.     repnz    scasb
  230.     sub    edi,esi
  231.     mov    ecx,edi    
  232.     lea    edi,[ebp+Procdump.WindowName]
  233.     rep    movsb
  234.     stosb
  235.  
  236.     lea    esi,[ebp+Procdump]
  237.     mov    ecx,Bhrama_Struc.end-Procdump
  238.     call    CopyToUserLand
  239.     or    eax,eax
  240.     jnz    .1
  241.  
  242.     pop    ebx
  243.     mov    cr0,ebx
  244.     lea    ebx,[ebp+Error_NoUser]
  245.     jmp    Parser.error
  246.  
  247. .1:
  248.     mov    dword [ebp+dClient_EBP],eax
  249.     mov    dword [ebp+dClient_EIP],eax    ; set client (E)IP
  250.     mov    dword [ebp+dClient_ESP],eax    ; set client (E)SP
  251.     sub    dword [ebp+dClient_ESP],byte 4
  252.     mov    dword [ebp+oPAGEIN_INT3],eax    ; set address of final INT3
  253.     add    dword [ebp+oPAGEIN_INT3],byte Procdump.return-Procdump
  254.  
  255.     mov    ebx,[ebp+API.oGetCurrentProcessID]
  256.     mov    [eax+Procdump.oGetCurrentProcessID-Procdump-4],ebx
  257.     sub    [eax+Procdump.oGetCurrentProcessID-Procdump-4],eax
  258.     sub    dword [eax+Procdump.oGetCurrentProcessID-Procdump-4],byte Procdump.oGetCurrentProcessID-Procdump
  259.  
  260.     mov    ebx,[ebp+API.oFindWindowA]
  261.     mov    [eax+Procdump.oFindWindowA-Procdump-4],ebx
  262.     sub    [eax+Procdump.oFindWindowA-Procdump-4],eax
  263.     sub    dword [eax+Procdump.oFindWindowA-Procdump-4],byte Procdump.oFindWindowA-Procdump
  264.  
  265.     mov    ebx,[ebp+API.oSendMessageA]
  266.     mov    [eax+Procdump.oSendMessageA-Procdump-4],ebx
  267.     sub    [eax+Procdump.oSendMessageA-Procdump-4],eax
  268.     sub    dword [eax+Procdump.oSendMessageA-Procdump-4],byte Procdump.oSendMessageA-Procdump
  269.  
  270.     mov    [eax+Procdump.DataPointer-Procdump],eax
  271.     add    dword [eax+Procdump.DataPointer-Procdump],byte Bhrama_Struc-Procdump
  272.  
  273.     lea    eax,[eax+Procdump.WindowName-Procdump]
  274.     mov    [ebp+dClient_ESI],eax        ; bhrama server's window name
  275.  
  276.     pop    ebx
  277.     mov    cr0,ebx
  278.  
  279.     xor    eax,eax
  280.     inc    eax
  281.  
  282.     mov    [ebp+fPAGEIN_InProgress],eax    ; set internal Winice flag to 1
  283.     mov    [ebp+fExecuteMoreCommands],ah    ; set internal Winice flag to 0
  284.  
  285.     popad
  286.     retn
  287.  
  288.  
  289. ; ------------------------------------------------------------------------------
  290. ; this is where we call Procdump based on Stone's example
  291. ;
  292. ; ebp: linear address of Procdump on client stack
  293. ; esi: Bhrama window name
  294. ; ------------------------------------------------------------------------------
  295.     align 4
  296. Procdump:
  297.     call    .oGetCurrentProcessID
  298. .oGetCurrentProcessID:
  299.  
  300.     mov    [ebp+Bhrama_Struc+BhramaComStruc.PID-Procdump],eax
  301. ;    mov    [Bhrama_Struc+BhramaComStruc.EIP],0x0
  302. ;    mov    [Bhrama_Struc+BhramaComStruc.OptL1],0x00000000
  303. ;    mov    [Bhrama_Struc+BhramaComStruc.OptL2],0x01000001
  304. ;    mov    [Bhrama_Struc+BhramaComStruc.OptL3],0x01010001
  305. ;    mov    [Bhrama_Struc+BhramaComStruc.OptL4],0x00010000
  306. ;    mov    [Bhrama_Struc+BhramaComStruc.OptL5],0x00000000
  307.  
  308. ; LookUp for ProcDump Server.
  309.     push    esi
  310.     push    byte 0
  311.     call    .oFindWindowA
  312. .oFindWindowA:
  313.  
  314.     test    eax,eax
  315.     jz    .return
  316.  
  317. ; Send Dump Message to ProcDump Server.
  318. .sendmsg:
  319.     add    ebp,byte .Service-Procdump
  320.     push    ebp
  321.     push    byte 0
  322.     push    byte WM_COPYDATA
  323.     push    eax            ; ProcDump's hwnd
  324.     call    .oSendMessageA
  325. .oSendMessageA:
  326.  
  327. .return:
  328.     int3
  329.  
  330.  
  331.     align 4
  332. .WindowName:    times 64 db 0
  333.  
  334.     align 4
  335. .Service:    dd 1
  336. .DataLength:    dd BhramaComStruc_size
  337. .DataPointer:    dd Bhrama_Struc
  338.  
  339. Bhrama_Struc:
  340. istruc BhramaComStruc
  341.   at BhramaComStruc.version,    dd 3
  342.   at BhramaComStruc.PID,    dd 0
  343.   at BhramaComStruc.EIP,    dd 0
  344.   at BhramaComStruc.OptL1,    dd 0x00000000
  345.   at BhramaComStruc.OptL2,    dd 0x01000101
  346.   at BhramaComStruc.OptL3,    dd 0x01010001
  347.   at BhramaComStruc.OptL4,    dd 0x00030000
  348.   at BhramaComStruc.OptL5,    dd 0x00000000
  349. iend
  350. .end:
  351.  
  352.  
  353. Parse_Dump:
  354.     call    pSkipWhiteSpace
  355.     jz    .set_pth_mode
  356.  
  357.     lea    ebx, [ebp+evl_err]
  358.     call    pExpression2Integer    ; Parse address
  359.     jb    near Parser.error
  360.  
  361.     mov    [ebp+dClient_EDI], eax    ; store address in Client_EDI
  362.     mov    dword [ebp+dClient_EAX], Srv_Dump    ; srv code goes in EAX
  363.     call    pSkipWhiteSpace
  364.     jz    .emulate        ; emulate old PAGEIN behaviour
  365.  
  366.     call    pExpression2Integer    ; Parse Length
  367.     jb    near Parser.error
  368.  
  369.     call    pSkipWhiteSpace        ; advance to filename
  370.     jnz    .cont            ; ESI: pointer to file name
  371.  
  372.     jmp    Parser.exit
  373.  
  374. .set_pth_mode:
  375.     xor    byte [ebp+PathMode], 1
  376.     lea    ebx, [ebp+msg_p0]
  377.     jnz    .on
  378.  
  379.     lea    ebx, [ebp+msg_p1]
  380. .on:
  381.     jmp    Parser.error
  382.  
  383. .emulate:
  384.     xor    eax, eax        ; Zero length
  385.     xor    esi, esi        ; No file name
  386.     jmp    .exprt_mode
  387.  
  388. .cont:
  389.     cmp    byte [ebp+PathMode], 1
  390.     jz    .exprt_mode
  391.     sub    esi, 4
  392.     mov    dword [esi], '\??\'
  393.  
  394. .exprt_mode:
  395.     mov    [ebp+dClient_ESI], esi    ; pointer to filename
  396.     mov    [ebp+dClient_ECX], eax    ; store length
  397.     call    CanResume        ; are we allowed to play the game ?
  398.  
  399.     test    byte [ebp+dClient_CS], 3    ; ring-0 Client ?
  400.     jz    near .ring0
  401.  
  402.     mov    ecx, EntryPoint.end - EntryPoint; number of bytes to copy
  403.     push    ecx
  404.  
  405.     lea    eax, [ebp+EntryPoint]        ; EAX: source
  406.     push    eax
  407.  
  408.     test    byte [ebp+dClient_EFLAGS+2], 2    ; V86 mode client?
  409.     jz    .PM
  410.  
  411.     mov    eax,cr4
  412.     test    eax,1                ; CR4.VME
  413.     jz    .set_iopl
  414.  
  415.     str    ax
  416.     call    pMapSelectorToLinAddr
  417.     jnc    .set_redirection
  418.  
  419.     lea    ebx, [ebp+tss_err]
  420.     push    ebx
  421.     call    pPrintErrorToCommandWindow
  422.     jmp    Parser.exit
  423.  
  424. .set_redirection:
  425.     movzx    edi, word [eax+0x66]        ; start of i/o perm map
  426.     lea    edi, [edi+eax-0x20]        ; start of int redir map
  427.     mov    eax, 0xFF            ; our interrupt
  428.     bts    [edi], eax            ; no redirection to V86 handler
  429.  
  430. .set_iopl:
  431.     mov    eax, [ebp+dClient_EFLAGS]        ; save IOPL
  432.     mov    [ebp+dClient_EBX], eax
  433.     or    byte [ebp+dClient_EFLAGS+1], 0x30    ; IOPL=3
  434.  
  435.     movzx    eax, word [ebp+dClient_SS]
  436.     mov    [ebp+dClient_CS], eax        ; set new client CS
  437.     shl    eax, 4
  438.     movzx    edi, word [ebp+dClient_ESP]
  439.     sub    edi, ecx            ; bug, should handle underflow
  440.     add    eax, edi
  441.     push    eax
  442.     jmp    short .copy
  443.  
  444. .PM:
  445.     movzx    eax, word [ebp+dClient_SS]
  446.     call    pMapSelectorToLinAddr
  447.     jnc    .got_linaddr
  448.  
  449.     add    esp, byte 8
  450.     lea    ebx, [ebp+sel_err]
  451.     jmp    Parser.error
  452.  
  453. .got_linaddr:
  454.     mov    edi, eax
  455.     add    edi, [ebp+dClient_ESP]        ; EDI: linear Client ESP
  456.     sub    edi, ecx            ; EDI destination ( on client Stack )
  457.     push    edi
  458.     mov    word [ebp+dClient_CS], 0x1B    ; set new client CS
  459.     mov    word [ebp+dClient_SS], 0x23    ; set new client SS
  460.  
  461. .copy:
  462.     call    pMemcopy            ; memcpy with protection from faults
  463.     lea    ebx, [ebp+stk_err]
  464.     test    eax, eax
  465.     jz    near Parser.error
  466.  
  467.     mov    ebx, edi            ; EBX: new EIP
  468.     lea    eax, [edi+EntryPoint.i3-EntryPoint]; EAX: INT3 location
  469.     mov    [ebp+dClient_ESP], edi        ; adjust client stack  
  470.     jmp    short .setup
  471.  
  472. .ring0:
  473.     lea    eax, [ebp+EntryPoint.i3]    ; INT3 location for ring-0 code
  474.     lea    ebx, [ebp+EntryPoint]        ; Get EIP
  475.  
  476. .setup:
  477.     mov    [ebp+oPAGEIN_INT3], eax        ; register INT3 location
  478.     mov    [ebp+dClient_EIP], ebx        ; set new client EIP
  479.     xor    eax, eax
  480.     inc    eax
  481.     mov    [ebp+fPAGEIN_InProgress], eax    ; set PAGEIN internal var
  482.     mov    [ebp+fExecuteMoreCommands], ah    ; leave ntice    
  483.     popad
  484.     retn
  485.  
  486. PathMode:    db 1
  487.  
  488.  
  489. Parse_Load:
  490.     call    pSkipWhiteSpace
  491.     jz    .set_pth_mode
  492.  
  493.     lea    ebx, [ebp+evl_err]
  494.     call    pExpression2Integer    ; Parse address
  495.     jb    near Parser.error
  496.  
  497.     mov    [ebp+dClient_EDI], eax    ; store address in Client_EDI
  498.     mov    dword [ebp+dClient_EAX], Srv_Load    ; srv code goes in EAX
  499.     call    pSkipWhiteSpace
  500.     jz    near Parser.error
  501.  
  502.     call    pExpression2Integer    ; Parse Length
  503.     jb    near Parser.error
  504.  
  505.     call    pSkipWhiteSpace        ; advance to filename
  506.     jnz    .cont            ; ESI: pointer to file name
  507.  
  508.     jmp    Parser.exit
  509.  
  510. .set_pth_mode:
  511.     xor    byte [ebp+PathMode], 1
  512.     lea    ebx, [ebp+msg_p0]
  513.     jnz    .on
  514.  
  515.     lea    ebx, [ebp+msg_p1]
  516. .on:
  517.     jmp    Parser.error
  518.  
  519. .cont:
  520.     cmp    byte [ebp+PathMode], 1
  521.     jz    .exprt_mode
  522.  
  523.     sub    esi, 4
  524.     mov    dword [esi], '\??\'
  525.  
  526. .exprt_mode:
  527.     mov    [ebp+dClient_ESI], esi    ; pointer to filename
  528.     mov    [ebp+dClient_ECX], eax    ; store length
  529.     call    CanResume        ; are we allowed to play the game ?
  530.  
  531.     test    byte [ebp+dClient_CS], 3    ; ring-0 Client ?
  532.     jz    near .ring0
  533.  
  534.     mov    ecx, EntryPoint.end - EntryPoint; number of bytes to copy
  535.     push    ecx
  536.  
  537.     lea    eax, [ebp+EntryPoint]        ; EAX: source
  538.     push    eax
  539.  
  540.     test    byte [ebp+dClient_EFLAGS+2], 2    ; V86 mode client?
  541.     jz    .PM
  542.  
  543.     mov    eax,cr4
  544.     test    eax,1                ; CR4.VME
  545.     jz    .set_iopl
  546.  
  547.     str    ax
  548.     call    pMapSelectorToLinAddr
  549.     jnc    .set_redirection
  550.  
  551.     lea    ebx, [ebp+tss_err]
  552.     push    ebx
  553.     call    pPrintErrorToCommandWindow
  554.     jmp    Parser.exit
  555.  
  556. .set_redirection:
  557.     movzx    edi, word [eax+0x66]        ; start of i/o perm map
  558.     lea    edi, [edi+eax-0x20]        ; start of int redir map
  559.     mov    eax, 0xFF            ; our interrupt
  560.     bts    [edi], eax            ; no redirection to V86 handler
  561.  
  562. .set_iopl:
  563.     mov    eax, [ebp+dClient_EFLAGS]        ; save IOPL
  564.     mov    [ebp+dClient_EBX], eax
  565.     or    byte [ebp+dClient_EFLAGS+1], 0x30    ; IOPL=3
  566.  
  567.     movzx    eax, word [ebp+dClient_SS]
  568.     mov    [ebp+dClient_CS], eax        ; set new client CS
  569.     shl    eax, 4
  570.     movzx    edi, word [ebp+dClient_ESP]
  571.     sub    edi, ecx            ; bug, should handle underflow
  572.     add    eax, edi
  573.     push    eax
  574.     jmp    short .copy
  575.  
  576. .PM:
  577.     movzx    eax, word [ebp+dClient_SS]
  578.     call    pMapSelectorToLinAddr
  579.     jnc    .got_linaddr
  580.  
  581.     add    esp, byte 8
  582.     lea    ebx, [ebp+sel_err]
  583.     jmp    Parser.error
  584.  
  585. .got_linaddr:
  586.     mov    edi, eax
  587.     add    edi, [ebp+dClient_ESP]        ; EDI: linear Client ESP
  588.     sub    edi, ecx            ; EDI destination ( on client Stack )
  589.     push    edi
  590.     mov    word [ebp+dClient_CS], 0x1B    ; set new client CS
  591.     mov    word [ebp+dClient_SS], 0x23    ; set new client SS
  592.  
  593. .copy:
  594.     call    pMemcopy            ; memcpy with protection from faults
  595.     lea    ebx, [ebp+stk_err]
  596.     test    eax, eax
  597.     jz    near Parser.error
  598.  
  599.     mov    ebx, edi            ; EBX: new EIP
  600.     lea    eax, [edi+EntryPoint.i3-EntryPoint]; EAX: INT3 location
  601.     mov    [ebp+dClient_ESP], edi        ; adjust client stack  
  602.     jmp    short .setup
  603.  
  604. .ring0:
  605.     lea    eax, [ebp+EntryPoint.i3]    ; INT3 location for ring-0 code
  606.     lea    ebx, [ebp+EntryPoint]        ; Get EIP
  607.  
  608. .setup:
  609.     mov    [ebp+oPAGEIN_INT3], eax        ; register INT3 location
  610.     mov    [ebp+dClient_EIP], ebx        ; set new client EIP
  611.     xor    eax, eax
  612.     inc    eax
  613.     mov    [ebp+fPAGEIN_InProgress], eax    ; set PAGEIN internal var
  614.     mov    [ebp+fExecuteMoreCommands], ah    ; leave ntice    
  615.     popad
  616.     retn
  617.  
  618.  
  619. ;-------------------------------------------------------------------------------
  620. ; Check if we are allowed to tweak client execution. In case of error, it
  621. ; will NOT return to the caller.
  622. ;-------------------------------------------------------------------------------
  623. CanResume:
  624.     call    pGetIRQLLevel            ; Get current IRQL level
  625.     lea    ebx, [ebp+irq_err]
  626.     cmp    eax, byte 2            ; IRQL > Dispatch_Level ?
  627.     jnb    .error
  628.  
  629.     lea    ebx, [ebp+int_err]
  630.     test    byte [ebp+dClient_EFLAGS+1], 2    ; interrupts enabled
  631.     jz    .error                ; nope, bye
  632.  
  633.     lea    ebx, [ebp+ctx_err]
  634.     mov    eax, [ebp+dCurrentContext]
  635.     cmp    eax, [ebp+dPopupContext]
  636.     jnz    .error
  637.  
  638.     retn
  639.  
  640. .error:
  641.     pop    eax        ; Remove return address from stack
  642.     jmp    Parser.error    ; and branch command parser exit
  643.                 ; That's it, return to NTICE, 
  644.                 ; nothing to be done
  645.  
  646.  
  647. ;------------------------------------------------------------------------------------ 
  648. ; client EAX: service ID
  649. ; client EBX: EFLAGS having original IOPL, only for V86 mode
  650. ;
  651. ; rest is service dependent
  652. ;------------------------------------------------------------------------------------ 
  653. EntryPoint:
  654.     int    0xFF        ; Initiate an extension call
  655. .i3:
  656.     int3            ; Break back in NTICE
  657. .end:
  658.  
  659. Icall_handler:
  660.     ExceptionFrame2KeTrapFrame HW_ERROR_CODE_OFF, PRIMARY
  661.     call    .delta
  662. .delta:
  663.     pop    esi                     
  664.     sub    esi, .delta
  665.  
  666.     test    byte [ebp+KeTrapFrame.EFLAGS+2], 2    ; EFLAGS.VM
  667.     jz    .PM
  668.  
  669.     mov    eax, [ebp+KeTrapFrame.EBX]    ; grab EFLAGS
  670.     mov    [ebp+KeTrapFrame.EFLAGS], eax    ; restore IOPL
  671.  
  672. .PM:
  673.     mov    eax, [ebp+KeTrapFrame.EAX]    ; grab service ID
  674.     mov    [ebp+KeTrapFrame.EAX], esi    ; Save ntice base in the trap frame
  675.     add    esi, tInternalApiTable        ; ESI: ptr to extension routines table
  676.     sti                             
  677.     call    [esi+eax*4]            ; call requested service
  678.     cli
  679.     KeTrapFrame2ExceptionFrame HW_ERROR_CODE_ON, PRIMARY
  680.     iretd
  681.  
  682.  
  683. ;-------------------------------------------------------------------------------
  684. SrvVer:
  685.     retn
  686.  
  687. ;-------------------------------------------------------------------------------
  688. SrvDump:
  689.     mov    eax, ebp            ; EAX : trape frame ptr
  690.     push    ebp                ; save trape frame ptr        
  691.     sub    esp, 8+8+24+8+4
  692.     mov    ebp, esp
  693.     mov    esi, [eax+KeTrapFrame.EAX]    ; 
  694.     lea    edi, [esi+CallTable]        ; EDI: ntoskrnl import table    
  695.     cmp    dword [eax+KeTrapFrame.ESI], byte 0    ; Do we have a filename ptr ?
  696.     jz    near .emulate            ; If no , emulate old PAGEIN 
  697.                         ; [ebp+52] == Trap frame ptr
  698.                         ; [ebp+48] == FileHandle                  
  699.                         ; EBP+40 == IoStatusBlock                                   
  700.                         ; EBP+16 == Object Attributes
  701.                         ; EBP+8  == AnsiString
  702.                         ; EBP == UnicodeString        
  703.  
  704.     lea    eax, [ebp+16]            ; get ptr to Object Attributes
  705.     InitializeObjectAttributes  ebp , dword 0x40 , dword 0 , dword 0
  706.     mov    eax, [ebp+52]            ; EAX: ptr Trap frame
  707.     push    dword [eax+KeTrapFrame.ESI]
  708.     lea    eax, [ebp+8]            ; OUT PANSI_STRING    
  709.     push    eax
  710.     call    [edi+RtlInitAnsiString]
  711.  
  712.     push    byte 1                ; Allocate Destination String Buffer
  713.     lea    eax, [ebp+8]            ; IN PANSI_STRING
  714.     push    eax
  715.     push    ebp                ; OUT PUNICODE_STRING
  716.     call    [edi+RtlAnsiStringToUnicodeString]
  717.  
  718.     push    byte 0
  719.     push    byte 0
  720.     push    dword 0x850                   
  721.     push    byte 5                ; FILE_SUPERSEED
  722.     push    byte 0                ; no sharing
  723.     push    dword 0x80            ; FILE_ATTRIBUTE_NORMAL
  724.     push    byte 0                ; allocation size 0
  725.     lea    eax, [ebp+40]            ; EAX: PIO_STATUS_BLOCK
  726.     push    eax
  727.     lea    eax, [ebp+16]            ; EAX: POBJECT_ATTRIBUTES
  728.     push    eax
  729.     push    dword 0x120116            ; Desired Access
  730.     lea    eax, [ebp+48]            ; ptr File Handle
  731.     push    eax
  732.     lea    ebx, [esi+opn_err]
  733.     call    [edi+ZwCreateFile]    
  734.     test    eax, eax
  735.     jl    .free_string
  736.  
  737.     push    byte 0                ; No KEY
  738.     push    byte 0                ; Null File Offset
  739.     mov    eax, [ebp+52]
  740.     push    dword [eax+KeTrapFrame.ECX]    ; Length
  741.     push    dword [eax+KeTrapFrame.EDI]    ; buffer address
  742.     lea    eax, [ebp+40]            ; PIO_STATUS_BLOCK
  743.     push    eax
  744.     push    byte 0                ; null APC context 
  745.     push    byte 0                ; no APC
  746.     push    byte 0                ; no completion Event
  747.     push    dword [ebp+48]            ; File handle
  748.     lea    ebx, [esi+wrt_err]
  749.     call    [edi+ZwWriteFile]
  750.     test    eax, eax
  751.     jl    .free_close
  752.  
  753.     push    ebp
  754.     call    [edi+RtlFreeUnicodeString]    ; Free temp unicode storage space
  755.  
  756.     push    dword [ebp+48]
  757.     call    [edi+ZwClose]            ; Close the file
  758.     jmp    short .return
  759.  
  760. .emulate:
  761.     lea    ebx, [esi+npr_err]
  762.     mov    esi, [ebp+52]            ; ESI = ptr trap frame
  763.     mov    esi, [esi+KeTrapFrame.EDI]    ; ESI: pagein address    
  764.     push    esi
  765.     call    [edi+MmIsAddressValid]        ; check if it is a valid address
  766.     test    al, al
  767.     jz    .error
  768.  
  769.     mov    eax, [esi]            ; touch the page and bring it in
  770.  
  771. .return:
  772.     add    esp, 8+8+24+8+4
  773.     pop    ebp
  774.     retn                    ; return to Icall_Handler
  775.  
  776. .free_close:
  777.     push    dword [ebp+48]
  778.     call    [edi+ZwClose]
  779.  
  780. .free_string:
  781.     push    ebp
  782.     call    [edi+RtlFreeUnicodeString]
  783.  
  784. .error:
  785.     push    ebx                ; EBX: ptr to error msg
  786.     call    [edi+DbgPrint]            ; print error msg     
  787.     pop    eax                ; DbgPrint follows C calling convention
  788.     jmp    short .return
  789.  
  790.  
  791. ;-------------------------------------------------------------------------------
  792. SrvDumpX:
  793.     retn
  794.  
  795.  
  796. ;-------------------------------------------------------------------------------
  797. SrvSr:
  798.     retn
  799.  
  800.  
  801. ;-------------------------------------------------------------------------------
  802. SrvBhr:
  803.     retn
  804.  
  805.  
  806. ;-------------------------------------------------------------------------------
  807. SrvLoad:
  808.     mov    eax, ebp            ; EAX : trape frame ptr
  809.     push    ebp                ; save trape frame ptr        
  810.     sub    esp, 8+8+24+8+4
  811.     mov    ebp, esp
  812.     mov    esi, [eax+KeTrapFrame.EAX]
  813.     lea    edi, [esi+CallTable]        ; EDI: ntoskrnl import table    
  814.  
  815.                         ; [ebp+52] == Trap frame ptr
  816.                         ; [ebp+48] == FileHandle                  
  817.                         ; EBP+40 == IoStatusBlock                                   
  818.                         ; EBP+16 == Object Attributes
  819.                         ; EBP+8  == AnsiString
  820.                         ; EBP == UnicodeString        
  821.  
  822.     lea    eax, [ebp+16]            ; get ptr to Object Attributes
  823.     InitializeObjectAttributes  ebp , dword 0x40 , dword 0 , dword 0
  824.     mov    eax, [ebp+52]            ; EAX: ptr Trap frame
  825.     push    dword [eax+KeTrapFrame.ESI]
  826.     lea    eax, [ebp+8]            ; OUT PANSI_STRING    
  827.     push    eax
  828.     call    [edi+RtlInitAnsiString]
  829.  
  830.     push    byte 1                ; Allocate Destination String Buffer
  831.     lea    eax, [ebp+8]            ; IN PANSI_STRING
  832.     push    eax
  833.     push    ebp                ; OUT PUNICODE_STRING
  834.     call    [edi+RtlAnsiStringToUnicodeString]
  835.  
  836.     push    byte 0
  837.     push    byte 0
  838.     push    dword 0x850
  839.     push    byte 1                ; FILE_OPEN
  840.     push    byte 1                ; share: read
  841.     push    byte 0                ; attribs don't apply
  842.     push    byte 0                ; allocation size 0
  843.     lea    eax, [ebp+40]            ; EAX: PIO_STATUS_BLOCK
  844.     push    eax
  845.     lea    eax, [ebp+16]            ; EAX: POBJECT_ATTRIBUTES
  846.     push    eax
  847.     push    dword 0x120109            ; Desired Access
  848.     lea    eax, [ebp+48]            ; ptr File Handle
  849.     push    eax
  850.     lea    ebx, [esi+opn_err]
  851.     call    [edi+ZwCreateFile]    
  852.     test    eax, eax
  853.     jl    .free_string
  854.  
  855.     push    byte 0                ; No KEY
  856.     push    byte 0                ; Null File Offset
  857.     mov    eax, [ebp+52]
  858.     push    dword [eax+KeTrapFrame.ECX]    ; Length
  859.     push    dword [eax+KeTrapFrame.EDI]    ; buffer address
  860.     lea    eax, [ebp+40]            ; PIO_STATUS_BLOCK
  861.     push    eax
  862.     push    byte 0                ; null APC context 
  863.     push    byte 0                ; no APC
  864.     push    byte 0                ; no completion Event
  865.     push    dword [ebp+48]            ; File handle
  866.     lea    ebx, [esi+wrt_err]
  867.     call    [edi+ZwReadFile]
  868.     test    eax, eax
  869.     jl    .free_close
  870.  
  871.     push    ebp
  872.     call    [edi+RtlFreeUnicodeString]    ; Free temp unicode storage space
  873.  
  874.     push    dword [ebp+48]
  875.     call    [edi+ZwClose]            ; Close the file
  876.  
  877. .return:
  878.     add    esp, 8+8+24+8+4
  879.     pop    ebp
  880.     retn                    ; return to Icall_Handler
  881.  
  882. .free_close:
  883.     push    dword [ebp+48]
  884.     call    [edi+ZwClose]
  885.  
  886. .free_string:
  887.     push    ebp
  888.     call    [edi+RtlFreeUnicodeString]
  889.  
  890. .error:
  891.     push    ebx                ; EBX: ptr to error msg
  892.     call    [edi+DbgPrint]            ; print error msg     
  893.     pop    eax                ; DbgPrint follows C calling convention
  894.     jmp    short .return
  895.  
  896.  
  897. ;------------------------------------------------------------------------------
  898. ; The following call will be assembled only if target NTICE version is 322,
  899. ; which does not have a pGetIrqlLevel in the form we expect. This call can be
  900. ; guaranteed as safe only in NT 4.0, since it relies on the hardcoded value of
  901. ; KPCR base
  902.  
  903. %if     NTICE_VERSION = 0x322
  904.  
  905. pGetIRQLLevel:
  906.     push    edi
  907.     mov    edi, KPCRSelfPointer+KPCR.Irql
  908.     call    pMOV_AL_EDI_safe
  909.     pop    edi
  910.     jc    .error
  911.  
  912.     movzx    eax, al
  913.     retn
  914.  
  915. .error:
  916.     mov    eax, 3
  917.     retn
  918. %endif
  919.  
  920.  
  921. ;-------------------------------------------------------------------------------
  922. ; ecx: amount, esi: dataptr, ebp: ntice base
  923. ;
  924. ; eax: destination or 0 on error
  925. ;-------------------------------------------------------------------------------
  926. CopyToUserLand:
  927.     xor    eax,eax
  928.  
  929.     cmp    dword [ebp+UserLandBuffer.size],byte 0
  930.     jz    .1
  931.  
  932.     retn
  933.  
  934. .1:
  935.     cmp    ecx,SAVEBUFFERSIZE
  936.     jb    .2
  937.  
  938.     retn
  939.  
  940. .2:
  941.     push    edi
  942.     mov    edi,[ebp+dClient_ESP]
  943.     and    edi,0xFFFFF000
  944.  
  945.     call    pMOV_AL_EDI_safe    ; is page present?
  946.     jnc    .3
  947.  
  948.     xor    eax,eax
  949.     pop    edi
  950.     retn
  951.  
  952. .3:
  953.     mov    [ebp+UserLandBuffer.size],ecx
  954.     mov    [ebp+UserLandBuffer.userptr],edi
  955.     mov    eax,edi            ; save 'cos we will return it
  956.  
  957.     push    ecx
  958.     push    esi
  959.  
  960.     mov    esi,edi            ; save user stack to temporary buffer
  961.     lea    edi,[ebp+UserLandBuffer.data]
  962.     rep    movsb
  963.  
  964.     pop    esi            ; copy data to the user stack
  965.     pop    ecx
  966.     mov    edi,eax
  967.     rep    movsb
  968.  
  969.     pop    edi
  970.     retn
  971.  
  972.  
  973. ;-------------------------------------------------------------------------------
  974. ; ebp: ntice base
  975. ;-------------------------------------------------------------------------------
  976. RestoreUserLand:
  977.     cmp    dword [ebp+UserLandBuffer.size],byte 0
  978.     jnz    .1
  979.  
  980.     retn
  981.  
  982. .1:
  983.     push    ecx
  984.     push    esi
  985.     push    edi
  986.     pushfd
  987.     cld
  988.  
  989.     mov    edi,[ebp+UserLandBuffer.userptr]
  990.     lea    esi,[ebp+UserLandBuffer.data]    ; copy data to the user stack
  991.     mov    ecx,[ebp+UserLandBuffer.size]
  992.     rep    movsb
  993.  
  994.     mov    dword [ebp+UserLandBuffer.size],0
  995.     mov    dword [ebp+UserLandBuffer.userptr],0
  996.  
  997.     popfd
  998.     pop    edi
  999.     pop    esi
  1000.     pop    ecx
  1001.     retn
  1002.  
  1003.  
  1004. ; save buffer, should be smaller than 4k (x86 page size)
  1005. SAVEBUFFERSIZE    equ 512
  1006.     align 4
  1007. UserLandBuffer:
  1008. .data:    times SAVEBUFFERSIZE db 0
  1009. .size:        dd 0
  1010. .userptr:    dd 0
  1011.  
  1012.  
  1013. ;-------------------------------------------------------------------------------
  1014. ; call RestoreUserLand while cleanup after a PAGEIN like int3
  1015. ;-------------------------------------------------------------------------------
  1016. HookCleanupForPAGEIN:
  1017.     push    ebp
  1018.     call    .delta
  1019. .delta:
  1020.     pop    ebp
  1021.     sub    ebp,.delta
  1022.     call    RestoreUserLand
  1023.     pop    ebp
  1024.     jmp    pMemcopy
  1025.  
  1026.  
  1027. ;-------------------------------------------------------------------------------
  1028. ; resolve win32 api symbols
  1029. ;-------------------------------------------------------------------------------
  1030. GetAPIs:
  1031.     push    esi
  1032.     push    ecx
  1033.     push    ebx
  1034.     push    eax
  1035.  
  1036.     or    ecx,byte -1
  1037.  
  1038.     mov    ebx,cr0
  1039.     push    ebx
  1040.     btr    ebx,16
  1041.     mov    cr0,ebx
  1042.  
  1043. .loop:
  1044.     inc    ecx
  1045.     cmp    dword [8*ecx+ebp+API+4],byte 0
  1046.     jnz    .1
  1047.  
  1048.     pop    ebx
  1049.     mov    cr0,ebx
  1050.  
  1051.     pop    eax
  1052.     pop    ebx
  1053.     pop    ecx
  1054.     pop    esi
  1055.  
  1056.     clc
  1057.     retn
  1058.  
  1059. .1:
  1060.     cmp    dword [8*ecx+ebp+API],byte 0
  1061.     jnz    .loop
  1062.  
  1063.     mov    esi,[8*ecx+ebp+API+4]
  1064.     add    esi,ebp
  1065.     
  1066.     call    pExpression2Integer
  1067.     jnb    .2
  1068.  
  1069.     pop    ebx
  1070.     mov    cr0,ebx
  1071.  
  1072.     pop    eax
  1073.     pop    ebx
  1074.     pop    ecx
  1075.     pop    esi
  1076.  
  1077.     stc
  1078.     retn
  1079.  
  1080. .2:
  1081.     mov     [8*ecx+ebp+API],eax
  1082.     jmp    short .loop
  1083.  
  1084.  
  1085.     align 4
  1086.  
  1087. API:
  1088. .oGetCurrentProcessID:    dd 0, .GetCurrentProcessID
  1089. .oFindWindowA:        dd 0, .FindWindowA
  1090. .oSendMessageA:        dd 0, .SendMessageA
  1091. ;.oOpenProcess:        dd 0, .OpenProcess
  1092. ;.oResumeThread:        dd 0, .ResumeThread
  1093. ;.oSuspendThread:    dd 0, .SuspendThread
  1094. ;.oExitThread:        dd 0, .ExitThread
  1095. ;.oExitProcess:        dd 0, .ExitProcess
  1096. ;.oTerminateThread:    dd 0, .TerminateThread
  1097. ;.oTerminateProcess:    dd 0, .TerminateProcess
  1098.  
  1099. ; null record, do not remove
  1100.             dd 0, 0
  1101.  
  1102. .GetCurrentProcessID:    db 'GetCurrentProcessID',0
  1103. .FindWindowA:        db 'FindWindowA',0
  1104. .SendMessageA:        db 'SendMessageA',0
  1105. ;.OpenProcess:        db 'OpenProcess',0
  1106. ;.ResumeThread:        db 'ResumeThread',0
  1107. ;.SuspendThread:        db 'SuspendThread',0
  1108. ;.ExitThread:        db 'ExitThread',0
  1109. ;.ExitProcess:        db 'ExitProcess',0
  1110. ;.TerminateThread:    db 'TerminateThread',0
  1111. ;.TerminateProcess:    db 'TerminateProcess',0
  1112.  
  1113.  
  1114. tImportNameTable: 
  1115.     db 'ZwCreateFile',0
  1116.     db 'ZwReadFile',0
  1117.     db 'ZwWriteFile',0
  1118.     db 'ZwClose',0
  1119.     db 'RtlAnsiStringToUnicodeString',0
  1120.     db 'RtlInitAnsiString',0
  1121.     db 'DbgPrint',0
  1122.     db 'RtlFreeUnicodeString',0
  1123.     db 'MmIsAddressValid',0
  1124.     db 'ZwSetInformationFile',0
  1125.     db 'KeAttachProcess',0
  1126.     db 'KeDetachProcess',0
  1127.     db 'KeInitializeDpc',0
  1128.     db 'KeInsertQueueDpc',0
  1129.  
  1130. tKernel32NameTable:      
  1131.  
  1132.  
  1133.     align 4
  1134. CallTable:    TIMES MaxImportId db 'SRVC'
  1135.  
  1136. tInternalApiTable:
  1137.     dd      SrvVer                     ;0 - version
  1138.     dd      SrvDump                    ;1 - dump
  1139.     dd      SrvSr                      ;2 - suspend
  1140.     dd      SrvSr                      ;3 - resume
  1141.     dd    SrvBhr               ;4 - bhrama
  1142.     dd    SrvDumpX           ;5 - extended dump
  1143.     dd    SrvLoad               ;6 - load
  1144.  
  1145.  
  1146. ;-------------------------------------------------------------------------------
  1147. ; flag variables
  1148. ;-------------------------------------------------------------------------------
  1149.  
  1150.             
  1151.  
  1152. ;-------------------------------------------------------------------------------
  1153. ; Error strings
  1154. ;-------------------------------------------------------------------------------
  1155. int_err    db 'Interrupts must be enabled to use this extension.',0
  1156. irq_err    db 'IRQL must be below DISPATCH_LEVEL to use this extension.',0
  1157. stk_err    db 'Cannot use this extension because current thread`s stack is not present.',0
  1158. tss_err    db 'Unable to determine TSS base',0
  1159. sel_err    db 'Client SS is invalid???',0
  1160. ctx_err    db 'Cannot dump from this context. Revert to pop-up context.',0
  1161. arg_err    db 'Arguments required.',0
  1162. evl_err    db 'Cannot evaluate expression.',0
  1163. prc_err    db 'Cannot attach an invalid process. Check KPEB parameter.',0
  1164. opn_err    db 'Failed to create output file. Possible reason: wrong path name.',CRLF_0
  1165. wrt_err    db 'Failed to dump requested data. Possible reason: invalid memory range.',CRLF_0
  1166. npr_err    db 'Page at specified address is either Reserved or Not Committed.',CRLF_0
  1167. msg_p0    db 'Path Expert mode is now on',0
  1168. msg_p1    db 'Path Expert mode is now off',0
  1169. nim_err    db 'Command currently not implemented.',0
  1170.  
  1171. Error_V86:    db 'EFLAGS.VM=1, only win32 clients are supported.',0
  1172. Error_PM16:    db 'CS.D=0, only win32 clients are supported.',0
  1173. Error_PMR0:    db 'CS.DPL=0, only win32 clients are supported.',0
  1174. Error_API:    db 'unable to resolve some win32 APIs, check winice.dat.',0
  1175. Error_NoID:    db 'specify PID/TID.',0
  1176. Error_NoWnd:    db 'specify Bhrama server window name',0
  1177. Error_NoUser:    db 'could not copy to user land',0
  1178.  
  1179. ;-------------------------------------------------------------------------------
  1180. ; Help strings
  1181. ;-------------------------------------------------------------------------------
  1182. help_d    db 'PAGEIN D <address> [ <length> <filename> ]',0
  1183. help_d1    db 'PAGEIN D',0
  1184. help_s    db 'PAGEIN S <KTEB>',0
  1185. help_r    db 'PAGEIN R <KTEB>',0
  1186. help_b    db 'PAGEIN B <Bhrama window name>',0
  1187. help_l    db 'PAGEIN L <address> <length> <filename>',0
  1188. help_v    db 'nticedump Beta 1 build 0009  http://icedump.tsx.org.',0
  1189.  
  1190. End:
  1191.